﻿// 粒子群算法.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
using namespace std;
#include<utility>
#include<random>
#include <chrono>
#include<set>
#include <random>
#include<cmath>
struct DIS {
    bool operator()(const std::pair<float,float>&a, const std::pair<float,float>& b) const {
        return (abs(a.first* a.first-a.second*a.second)) < abs((b.first*b.first-b.second*b.second));
    }
};
set<pair<int, int>, DIS> A;
float learningrateA = 1;
float learningrateB = 1;

class atom
{
public:
    pair<float, float> place;
    pair<float, float> speed;
    pair<float, float>sweet;
    float inertia;
    float rate;
    atom()
    {

    };
    atom(pair<float, float> A, pair<float, float>B, int D = 0.5)
    {
        place = A;
        speed = B;
        sweet = A;
        inertia = D;
        rate = 0;
    };
    float distance(pair<float,float>X)
    {
        float distance =abs(X.first * X.first - X.second * X.second);
        return distance;
    }
    void renewstom(pair<float,float>best)
    {
        // 创建随机数引擎
        unsigned seed = chrono::system_clock::now().time_since_epoch().count();
        mt19937 gen(seed);
        uniform_real_distribution<double> dis(0.0, 1.0);
        float speedx = speed.first;
        float speedy = speed.second;
        speedx = speedx * inertia;
        speedy = speedy * inertia;
        float random_num1 = dis(gen);
        float random_num2 = dis(gen);
        float newratex = speedx + learningrateA * random_num1 * (sweet.first - place.first) + learningrateB * random_num2 * (best.first - place.first);
        float newratey = speedy + learningrateB * random_num1 * (sweet.second - place.second) + learningrateB * random_num2 * (best.second - place.second);
        speed = make_pair(newratex, newratey);
        place = make_pair(place.first + newratex, place.second + newratey);
        if (distance(sweet) > distance(place))
        {
            sweet = place;
        };
       inertia =atan(distance(place))/7;
        return;
     /* float a = speed.first;
        float b = speed.second;
        float moral = 1.0 / (a * a + b * b);
        a = moral * a;
        b = moral * b;
        speed = make_pair(a, b);*/
        //速度归一化 
    };

};
int main()
{
    
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<float> dis1(-1000.0f, 10.0f);  // 生成大于-10小于10的浮点随机数
    std::uniform_real_distribution<float> dis2(-10.0f, 1000.0f);  // 生成大于-10小于0的浮点随机数
    atom SC[20];

    for (int i = 0; i < 20; i++)
    {
        float random1 = dis1(gen);
        float  random2 = dis2(gen);
         atom F(make_pair(random1, random2), make_pair(0, 0));
         SC[i] = F;
         A.insert(SC[i].place);
    }
    for (int i = 0; i < 20; i++)
    {
        cout << SC[i].place.first << " " << SC[i].place.second << endl;
    };
    for (int i = 0; i < 100; i++)
    {
        for (int j = 0; j < 20 ; j++)
        {
            SC[j].renewstom(*(A.begin()));
            A.insert(SC[i].place);
        }
    }
    for (int i = 0; i < 20; i++)
    {
        cout << SC[i].place.first << " " << SC[i].place.second << "    " << SC[i].distance(SC[i].place) << endl;
    }


}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
